#!/usr/bin/env python
# -*- coding: utf-8 -*-

# thirdpart modules
from PyQt5.QtCore import (
    QFile,
    QFileInfo,
    QIODevice,
    QResource,
    QSettings,
    QSignalMapper,
    QSize,
    QTextStream,
    Qt,
)

from PyQt5.QtGui import (
    QIcon,
    QKeySequence,
)

from PyQt5.QtWidgets import (
    QAction,
    QApplication,
    QDialog,
    QMainWindow,
    QMdiArea,
    QMessageBox,
    QStyle,
    QTabWidget,
    QWidget,
    qApp,
)

# auto generated
import Resources.Resources

# user defined
from Widgets.DockWindows.TabDockWindow import TabDockWindow
from Widgets.DockWindows.WinDockWindow import WinDockWindow
from Widgets.Dialogs.LogonDialog       import LogonDialog
from Widgets.MdiChilds import (MdiChild1, MdiChild2, MdiChild3)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.readResources()

        self.setTabPosition(Qt.DockWidgetArea.AllDockWidgetAreas, QTabWidget.TabPosition.South)
        self.mdiArea = QMdiArea()
        self.mdiArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mdiArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mdiArea.setViewMode(QMdiArea.TabbedView)
        self.mdiArea.setTabsClosable(True)
        self.mdiArea.setTabsMovable(True)
        self.mdiArea.setTabShape(QTabWidget.Rounded)
        self.setCentralWidget(self.mdiArea)

        self.mdiArea.subWindowActivated.connect(self.updateMenus)
        self.windowMapper = QSignalMapper(self)
        self.windowMapper.mapped[QWidget].connect(self.mdiArea.setActiveSubWindow)

        self.createActions()
        self.createMenus()
        self.createToolBars()
        self.createStatusBar()

        self.dockTab = TabDockWindow(parent = self)
        self.dockWin = WinDockWindow(parent = self)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockTab)
        self.tabifyDockWidget(self.dockTab, self.dockWin)
        self.dockTab.raise_()
        self.dockTab.viewItem.connect(self.viewItem)

        self.updateMenus()
        self.readSettings()
        self.setWindowTitle('RuleScripter')
        self.setWindowIcon(QIcon(':/Resources/Images/qt.png'))
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.centralWindow()

    def readResources(self):
        res = QResource(':/Resources/Text/table_list.txt')
        qfile = QFile(res.absoluteFilePath())
        qfile.open(QIODevice.ReadOnly | QIODevice.Text)
        infile = QTextStream(qfile)
        self.tableNames = infile.readAll().splitlines()

    def centralWindow(self):
        availableGeometry = qApp.desktop().availableGeometry()
        self.setGeometry(QStyle.alignedRect(
            Qt.LeftToRight,
            Qt.AlignCenter,
            QSize(availableGeometry.size() * 2/3),
            availableGeometry))

    def viewItem(self, item):
        # child = self.createMdiChild2(item.data())
        child = self.createMdiChild3(item.data())
        child.show()

    def closeEvent(self, event):
        self.mdiArea.closeAllSubWindows()
        if self.mdiArea.currentSubWindow():
            event.ignore()
        else:
            self.writeSettings()
            event.accept()

    def newFile(self):
        child = self.createMdiChild1()
        child.show()

    def save(self):
        pass

    def logon(self):
        logon = LogonDialog(self)
        if QDialog.Accepted != logon.exec_():
            return
        print(logon.getConnString())

    def logoff(self):
        pass

    def settings(self):
        pass

    def about(self):
        QMessageBox.about(self, 'About RuleScripter',
            'The <b>RuleScripter</b> example demonstrates how to write multiple '
            'document interface applications using Qt.')

    def updateMenus(self):
        hasMdiChild = (self.activeMdiChild() is not None)
        self.saveAct.setEnabled(hasMdiChild)
        self.closeAct.setEnabled(hasMdiChild)
        self.closeAllAct.setEnabled(hasMdiChild)
        self.tileAct.setEnabled(hasMdiChild)
        self.cascadeAct.setEnabled(hasMdiChild)
        self.nextAct.setEnabled(hasMdiChild)
        self.previousAct.setEnabled(hasMdiChild)
        self.separatorAct.setVisible(hasMdiChild)

    def updateWindowMenu(self):
        self.windowMenu.clear()
        self.windowMenu.addAction(self.closeAct)
        self.windowMenu.addAction(self.closeAllAct)
        self.windowMenu.addSeparator()
        self.windowMenu.addAction(self.tileAct)
        self.windowMenu.addAction(self.cascadeAct)
        self.windowMenu.addSeparator()
        self.windowMenu.addAction(self.nextAct)
        self.windowMenu.addAction(self.previousAct)
        self.windowMenu.addAction(self.separatorAct)

        windows = self.mdiArea.subWindowList()
        self.separatorAct.setVisible(len(windows) != 0)

        for (i, window) in enumerate(windows):
            child = window.widget()

            text = '%d %s' % (i + 1, child.userFriendlyCurrentFile())
            if i < 9:
                text = '&' + text

            action = self.windowMenu.addAction(text)
            action.setCheckable(True)
            action.setChecked(child is self.activeMdiChild())
            action.triggered.connect(self.windowMapper.map)
            self.windowMapper.setMapping(action, window)

    def createMdiChild1(self):
        child = MdiChild1()
        self.mdiArea.addSubWindow(child)
        return child

    def createMdiChild2(self, title):
        child = MdiChild2(title)
        self.mdiArea.addSubWindow(child)
        return child

    def createMdiChild3(self, title):
        child = MdiChild3(title)
        self.mdiArea.addSubWindow(child)
        return child

    def createActions(self):
        self.newAct = QAction(QIcon(':/Resources/Images/newdocument.png'),
            '&New', self, shortcut = QKeySequence.New, statusTip = 'Create a new file', triggered = self.newFile)

        self.saveAct = QAction(QIcon(':/Resources/Images/save.png'),
            '&Save ...', self, shortcut = QKeySequence.Save, statusTip = 'Save the document to disk', triggered = self.save)

        self.logonAct = QAction(QIcon(':/Resources/Images/play.png'),
            '&Logon ...', self, shortcut = 'Ctrl+L', statusTip = 'Logon database', triggered = self.logon)

        self.logoffAct = QAction(QIcon(':/Resources/Images/stop.png'),
            'Log&off', self, statusTip = 'Logoff database', triggered = self.logoff)

        self.settingAct = QAction(QIcon(':/Resources/Images/settings.png'),
            'Set&tings ...', self, statusTip = 'Show settings dialog', triggered = self.settings)

        self.exitAct = QAction('E&xit', self, shortcut = 'Ctrl+Q',
            statusTip = 'Exit the application', triggered = qApp.closeAllWindows)

        self.closeAct = QAction('Cl&ose', self, shortcut = 'Ctrl+F4',
            statusTip = 'Close the active window', triggered = self.mdiArea.closeActiveSubWindow)

        self.closeAllAct = QAction('Close &All', self,
            statusTip = 'Close all the windows', triggered = self.mdiArea.closeAllSubWindows)

        self.tileAct = QAction(QIcon(':/Resources/Images/tilewindowshorizontally.png'),
            '&Tile', self, statusTip = 'Tile the windows', triggered = self.mdiArea.tileSubWindows)

        self.cascadeAct = QAction(QIcon(':/Resources/Images/cascadewindows.png'),
            '&Cascade', self, statusTip = 'Cascade the windows', triggered = self.mdiArea.cascadeSubWindows)

        self.nextAct = QAction(QIcon(':/Resources/Images/gotonext.png'), 'Ne&xt', self, shortcut = QKeySequence.NextChild,
            statusTip = 'Move the focus to the next window', triggered = self.mdiArea.activateNextSubWindow)

        self.previousAct = QAction(QIcon(':/Resources/Images/gotoprevious.png'), 'Pre&vious', self, shortcut = QKeySequence.PreviousChild,
            statusTip = 'Move the focus to the previous window', triggered = self.mdiArea.activatePreviousSubWindow)

        self.separatorAct = QAction(self)
        self.separatorAct.setSeparator(True)

        self.aboutAct = QAction(QIcon(':/Resources/Images/help.png'), '&About', self,
            statusTip = 'Show the application\'s About box', triggered = self.about)

        self.aboutQtAct = QAction(QIcon(':/Resources/Images/qt.png'), 'About &Qt', self,
            statusTip = 'Show the Qt library\'s About box', triggered = qApp.aboutQt)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu('&File')
        self.fileMenu.addAction(self.newAct)
        self.fileMenu.addAction(self.saveAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.logonAct)
        self.fileMenu.addAction(self.logoffAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.settingAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        self.viewMenu = self.menuBar().addMenu('&View')

        self.windowMenu = self.menuBar().addMenu('&Window')
        self.updateWindowMenu()
        self.windowMenu.aboutToShow.connect(self.updateWindowMenu)

        self.menuBar().addSeparator()

        self.helpMenu = self.menuBar().addMenu('&Help')
        self.helpMenu.addAction(self.aboutAct)
        self.helpMenu.addAction(self.aboutQtAct)

    def createToolBars(self):
        self.fileToolBar = self.addToolBar('File')
        self.fileToolBar.setIconSize(QSize(16, 16))
        self.fileToolBar.addAction(self.newAct)
        self.fileToolBar.addAction(self.saveAct)
        self.fileToolBar.addSeparator()
        self.fileToolBar.addAction(self.logonAct)
        self.fileToolBar.addAction(self.logoffAct)
        self.fileToolBar.addSeparator()
        self.fileToolBar.addAction(self.settingAct)
        self.fileToolBar.addSeparator()

    def createStatusBar(self):
        self.statusBar().showMessage('Ready')

    def readSettings(self):
        pass

    def writeSettings(self):
        settings = QSettings('Trolltech', 'RuleScripter')
        settings.setValue('pos', self.pos())
        settings.setValue('size', self.size())

    def activeMdiChild(self):
        activeSubWindow = self.mdiArea.activeSubWindow()
        if activeSubWindow:
            return activeSubWindow.widget()
        return None

    def findMdiChild(self, fileName):
        canonicalFilePath = QFileInfo(fileName).canonicalFilePath()

        for window in self.mdiArea.subWindowList():
            if window.widget().currentFile() == canonicalFilePath:
                return window
        return None

if __name__ == '__main__':
    import sys

    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())
